package com.ly.mp.busicen.rule.flow;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

import org.springframework.util.StringUtils;

import com.ly.mp.busicen.common.constant.UserBusiEntity;
import com.ly.mp.busicen.rule.config.XruleExtendCfg;

public class FlowUserMode<T extends UserBusiEntity> {	
	
	/**
	 * 初始化用户调用
	 * @param <T>
	 * @param user
	 * @param supplier
	 * @return
	 */
	public static <S extends UserBusiEntity,T> T invoke(S user,Supplier<T> supplier) {
		try {
			FlowUserMode<S> flowUserMode = FlowUserMode.create();
			flowUserMode.setUser(user);
			FlowUserMode.setUserMode(flowUserMode);
			return supplier.get();
		} finally {
			FlowUserMode.resetUserMode();
		}
	}
	

	/**
	 * 初始化用户调用
	 * @param <T>
	 * @param user
	 * @param supplier
	 * @return
	 */
	public static <S extends UserBusiEntity> void invoke(S user,SupplierTemp supplier) {
		try {
			FlowUserMode<S> flowUserMode = FlowUserMode.create();
			flowUserMode.setUser(user);
			FlowUserMode.setUserMode(flowUserMode);
			supplier.get();
		} finally {
			FlowUserMode.resetUserMode();
		}
	}
	
	public static <T extends UserBusiEntity> FlowUserMode<T> create() {
		FlowUserMode<T> userMode = new FlowUserMode<>();		
		return userMode;
	}	
	
	private static ThreadLocal<FlowUserMode<? extends UserBusiEntity>> USERMODE = new ThreadLocal<>();
	
	public static  UserBusiEntity user() {
		if (USERMODE.get()==null) {
			return null;
		}
		return USERMODE.get().getUser();
	}
	
	public static boolean userMode() {
		if (USERMODE.get()==null) {
			return true;
		}
		return USERMODE.get().mode;
	}
	
	public static <T extends UserBusiEntity>  void setUserMode(FlowUserMode<T> userMode) {
		USERMODE.set(userMode);
	}
	
	public static void resetUserMode() {
		USERMODE.remove();
	}
	
	public static UserBusiEntity currentUser(){
		if (FlowUserMode.userMode()) {
			return XruleExtendCfg.currentUserSupplier().get();
		}else {
			return FlowUserMode.user();
		}
	}
	
	public static Map<String, Object> currentContext(String brand){
		Map<String, Object> ctx = new HashMap<>();
		if(XruleExtendCfg.brandCheck()) {
		    // 走这里
			String brandCode = StringUtils.isEmpty(brand)?FlowUserMode.currentUser().getBrandCode():brand;
			ctx.put("brandCode", brandCode);
			String oemCode = FlowUserMode.currentUser().getOemCode();
			ctx.put("oemCode", oemCode);
		}else {
			ctx.put("brandCode", "1");
			ctx.put("oemCode", "1");
		}
		return ctx;
	}
	
	private boolean mode = false;
	
	private T user;

	public boolean getMode() {
		return mode;
	}

	public void setMode(boolean mode) {
		this.mode = mode;
	}

	public T getUser() {
		return user;
	}

	public void setUser(T user) {
		this.user = user;
	}
	
	@FunctionalInterface
	public static interface SupplierTemp{
		
		void get();
		
	}
	
	
}
